#include <private/qobject_p.h>
#include <QQmlProperty>
#include <private/qqmlproperty_p.h>
#include "ROSharedObject.h"
#include "QQuickROData.h"
#include "ROHost.h"
#include "ROSignalConnection.h"

ROSharedObject::ROSharedObject(QObject *parent):ROSyncProperty(parent)
{

}

void ROSharedObject::initialize()
{
    ROSyncProperty::initialize();
    if(role() == Host)
    {
        observeAllProperty();
    }
}

QStringList ROSharedObject::allProperties()
{
    QStringList ret;
    auto meta = metaObject();
    for(auto i = ROSharedObject::staticMetaObject.propertyOffset();i< meta->propertyCount();i++)
    {
        auto prop = meta->property(i);
        ret << prop.name();
    }

    return ret;
}

QVariantMap ROSharedObject::extractProperties(const QStringList &prop)
{
    QVariantMap ret;

    for(auto i:prop)
    {
        ret[i] = property(i.toUtf8());
    }

    return ret;
}

void ROSharedObject::handleProperties(const QVariantMap &var)
{
    auto all = ROSharedObject::allProperties();
    for(auto i:all)
    {
        if(var.contains(i))
        {
            updateTargetProperty(this,i,var[i]);
        }
    }
}

void ROSharedObject::updateTargetProperty(QObject *target, const QString &propName, const QVariant &value)
{
    QQmlProperty prop(target,propName);
    QQmlPropertyPrivate::removeBinding(prop);//副本在接受源的数据时会抛弃自身的属性绑定
    target->setProperty(propName.toUtf8(),value);
}

void ROSharedObject::observeAllProperty()
{
    auto meta = metaObject();
    for(auto i : ROSharedObject::allProperties())
    {
        auto prop = meta->property(meta->indexOfProperty(i.toUtf8()));
        std::function<void()> func = [=](){
            this->propertyChanged(i);
        };
        ROSignalConnection::connect(this,prop.notifySignalIndex()).to(this).on(func,Qt::AutoConnection);
    }
}


